#pragma once

#include <memory>
#include <stdexcept>

#include "rtda/local_vars.h"
#include "rtda/operand_stack.h"
#include "rtda/thread.h"
#include "rtda/heap/method.h"

namespace jvm {
    namespace rtda {

        // 前向声明
        class Thread;
        class OperandStack;
        class LocalVars;
        // class heap::Method;

        class Frame {
        public:
            Frame(std::shared_ptr<Thread> thread = nullptr, std::shared_ptr<heap::Method> method = nullptr)
                : _p_method(method),
                _local_vars(method->getMaxLocals()),
                _p_operand_stack(std::make_shared<OperandStack>(_p_method->getMaxStack())),
                _p_thread(thread),
                _next_pc(0) {};

            Frame(const Frame&) = delete; // 禁止拷贝构造
            Frame& operator=(const Frame&) = delete; // 禁止赋值操作
            Frame(Frame&&) = default; // 允许移动构造
            Frame& operator=(Frame&&) = default; // 允许移动赋值
            ~Frame() = default;

            LocalVars& getLocalVars();

            std::shared_ptr<OperandStack> getOperandStack();

            std::shared_ptr<Thread> getThread();
            void setThread(std::weak_ptr<Thread> thread);

            uint32_t getNextPC() const;
            void setNextPC(uint32_t next_pc);

            std::shared_ptr<heap::Method> getMethod() const;

            void revertNextPC();

        private:
            std::shared_ptr<heap::Method> _p_method; // 当前方法
            LocalVars _local_vars;
            std::shared_ptr<OperandStack> _p_operand_stack;
            std::weak_ptr<Thread> _p_thread; // 线程
            uint32_t _next_pc; // 下一条指令的地址
        };

    } // namespace rtda
} // namespace jvm
